package org.light.domain;

import java.util.Iterator;
import java.util.Set;

import org.light.complexverb.TwoDomainVerb;
import org.light.exception.ValidateException;
import org.light.generator.NamedUtilMethodGenerator;
import org.light.utils.InterVarUtil;
import org.light.utils.StringUtil;

public class TwoDomainController extends Controller implements Comparable<Controller>{
	private static final long serialVersionUID = 229666513964270905L;
	protected TwoDomainVerb tverb;
	protected Domain master;
    protected Domain slave;
	
	public String generateControllerString()  throws Exception{
		this.tverb.setMaster(master);
        this.tverb.setSlave(slave);
		if (this.tverb.generateControllerMethod() == null) return null;
		//Method verbMethod = this.verb.generateFacadeMethod();
		//this.addMethod(verbMethod);
		StringBuilder sb = new StringBuilder();
		if (this.master.getPackageToken() !=null && !"".equalsIgnoreCase(this.master.getPackageToken())) sb.append("package ").append(this.master.getPackageToken()).append(".").append(this.master.getControllerSuffix()).append(";\n\n");
		Set<String> imports = this.generateImportStrings();
		for (String s: imports){
			sb.append("import ").append(s).append(";\n");
		}
		sb.append("import javax.servlet.annotation.WebServlet;\n");
		sb.append("\n");
		sb.append("@WebServlet(name = \""+StringUtil.lowerFirst(this.getStandardName())+"\",urlPatterns = \"/"+ this.master.getControllerPackagePrefix()+this.master.getLowerFirstDomainName()+this.master.getControllerNamingSuffix()+"/"+StringUtil.lowerFirst(this.tverb.getVerbName())+"\")\n");
		sb.append("public class ").append(this.getStandardName()).append(" extends HttpServlet{\n");		
		
		//generate fields notions
		Iterator it = this.getFields().iterator();
		  while (it.hasNext()) {	
		        Field field = (Field) it.next();
		        String fieldName = field.getFieldName();
		        String fieldType = field.getFieldType();
		        sb.append("\tprotected ").append(fieldType).append(" ").append(fieldName).append(";\n");
	        }
		  sb.append("\n");
		  //generate getter setter notions
		  it = this.getFields().iterator();
		  while (it.hasNext()) {	
		        Field field = (Field) it.next();
		        String fieldName = field.getFieldName();
		        String fieldType = field.getFieldType();
		        // generate setters
		        sb.append("\tpublic void set").append(StringUtil.capFirst(fieldName)).append("(").append(fieldType).append(" ").append(StringUtil.lowerFirst(fieldName)).append("){\n");
		        sb.append("\t\tthis.").append(StringUtil.lowerFirst(fieldName)).append(" = ").append(StringUtil.lowerFirst(fieldName)).append(";\n");
		        sb.append("\t}\n\n");
		        // generate getters
		        sb.append("\tpublic ").append(fieldType).append(" get").append(StringUtil.capFirst(fieldName)).append("(){;\n");
		        sb.append("\t\treturn this.").append(StringUtil.lowerFirst(fieldName)).append(";\n");
		        sb.append("\t}\n\n");
	        }
		  
		  Iterator it2 = this.getMethods().iterator();
		  while (it2.hasNext()){
			  sb.append(((Method)it2.next()).generateMethodString()).append("\n");
		  }
		  sb.append("}\n");
		return sb.toString();
	}

	public TwoDomainController(TwoDomainVerb  tverb, Domain master, Domain slave) throws Exception{
		super();
		tverb.setMaster(master);
        tverb.setSlave(slave);
		this.tverb = tverb;
		this.master = master;
        this.slave = slave;
		this.standardName = tverb.getVerbName() + master.getControllerNamingSuffix();
		
		ValidateInfo info = this.validate();
		if (info.success){
			try {
				Method processRequest = this.tverb.generateControllerMethod();
				Method doGet = NamedUtilMethodGenerator.generateServletDoGetCallProcessRequestMethod(2, InterVarUtil.Servlet.request, InterVarUtil.Servlet.response);
				Method doPost =  NamedUtilMethodGenerator.generateServletDoPostCallProcessRequestMethod(2, InterVarUtil.Servlet.request, InterVarUtil.Servlet.response);
				Method servletInfo = NamedUtilMethodGenerator.generateGetServletInfoMethod(2, "Powered by Mind Rules.");
				this.addMethod(processRequest);
				this.addMethod(servletInfo);
				this.addMethod(doGet);
				this.addMethod(doPost);
			} catch(Exception e) {
				e.printStackTrace();
			}
		}else {
			ValidateException e = new ValidateException(info);
			throw e;
		}
	}
	
	public TwoDomainController(){super();}

	@Override
	public int compareTo(Controller o) {
		String myName = this.getStandardName();
		String otherName = o.getStandardName();
		return myName.compareTo(otherName);
	}
}
